package fantasy;

import static com.google.appengine.api.labs.taskqueue.TaskOptions.Builder.url;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.labs.taskqueue.Queue;
import com.google.appengine.api.labs.taskqueue.QueueFactory;

public class SaveSingleLeagueServlet extends HttpServlet {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 4576837093872202689L;
	
	private static XPath xPath = XPATH.get().newXPath();
	
	private YahooParseXml yahooParser = new YahooParseXml();


	protected void service(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, IOException {
		
		String userkey = req.getParameter("user");
		
		Integer lnum = Integer.parseInt(req.getParameter("league"));
		
		if(userkey != null) {
			
			try {
				yahooParser.getXmlFromDS(userkey);
				NodeList nodes = yahooParser.getXmlNodes("//league");
				yahooParser.parseForStatics(nodes.item(lnum));
				saveLeague(nodes.item(lnum));
			} catch(JDOObjectNotFoundException e) {
				
			} catch (XPathExpressionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
		        Queue queue = QueueFactory.getDefaultQueue();
		        queue.add(url("/cron/savestandingworker").param("user", userkey).param("league", String.valueOf(lnum)));
			}
		} 
	}
	
	private void saveLeague(Node leagueNode) 
	  throws IOException, NumberFormatException, XPathExpressionException {

		PersistenceManager pm = PMF.get().getPersistenceManager();

		//Get all search Result nodes
		// Here I'm searching for the "stat" nodes within the XML.  At any level
		// Very roughly using http://java.sun.com/developer/technicalArticles/xml/validationxpath/
		// as a guide.
		
		NodeList nodesStats = (NodeList)xPath.evaluate("settings/stat_categories/stats/stat", leagueNode, XPathConstants.NODESET);
		int nodeCountStats = nodesStats.getLength();

		//iterate over search Result nodes
		Set<Key> statcategories = new HashSet<Key>();
		for (int i = 0; i < nodeCountStats; i++) {
			
		  Boolean savestat = false;

  		  Integer stat_id = Integer.parseInt((String)xPath.evaluate("stat_id", nodesStats.item(i), XPathConstants.STRING));
		  String key_gen = yahooParser.getGame_type() + "-" + stat_id.toString();

		  Transaction tx = pm.currentTransaction();
		  
	      try {
	    	  tx.begin();

			  Key key = new KeyFactory.Builder(StatCategory.class.getSimpleName(), key_gen).getKey();
			  StatCategory s;
	          try {
	        	  s = pm.getObjectById(StatCategory.class, key);
	          } catch (JDOObjectNotFoundException e) {
	    		  //Get each xpath variable
	        	  log("Stat Category was not found and is being created");
	        	  s = yahooParser.parseLeagueForCategories(nodesStats.item(i));
	        	  s.setKey(key);
	        	  
				  statcategories.add(key);
				  savestat = true;
	          }

	          if(savestat) {
	        	  pm.makePersistent(s);
	          }

	          tx.commit();

	      } finally {
	          if (tx.isActive()) {
	              tx.rollback();
	          }
	      }
		}

		Transaction tx2 = pm.currentTransaction();
		try {
	    	tx2.begin();
		    LeagueSettings league;

	        try {
	        	Key league_k = new KeyFactory.Builder(LeagueSettings.class.getSimpleName(), yahooParser.getLeague_key()).getKey();
	        	league = pm.getObjectById(LeagueSettings.class, league_k);
	        } catch (JDOObjectNotFoundException e) {
	        	log("League was not found and is being created");
	        	// Getting League
	        	league = yahooParser.parseLeagueForSettings(leagueNode);
	        	
	        	// Getting RosterPositions
	        	NodeList nodesRosters = (NodeList)xPath.evaluate("settings/roster_positions/roster_position", leagueNode, XPathConstants.NODESET);
	    		int nodeCountRosters = nodesRosters.getLength();
	    		Set<RosterPositions> rosterpositions = new HashSet<RosterPositions>();
	    		for (int i=0; i < nodeCountRosters; i++) {
	    			RosterPositions r = yahooParser.parseLeagueForPositions(nodesRosters.item(i));
	    			rosterpositions.add(r);
	    		}
	    		
	    		NodeList teamNodes = (NodeList)xPath.evaluate("standings/teams/team", leagueNode, XPathConstants.NODESET);
	    		int nodeTeamCount = teamNodes.getLength();
	    		Set<LeagueTeams> teams = new HashSet<LeagueTeams>();
	    		log("Team Node Count: " + nodeTeamCount);
	    		
	    		//Iterate over teams
	    		for (int i = 0; i < nodeTeamCount; i++) {

				  LeagueTeams t = yahooParser.parseLeagueForTeams(teamNodes.item(i));
	    		  teams.add(t);
	    		}
	    		
				league.setsRosterPositionSet(rosterpositions);
				league.setStats(statcategories);
				league.setLeagueTeams(teams);
	        }
	        
	    	pm.makePersistentAll(league);

	    	tx2.commit();

	    } finally {
	    	if (tx2.isActive()) {
	    		tx2.rollback();
	    	}
	    }
	    pm.close();
	    
	}
}
